<template>
  <view class="wind-field-container">
    <!-- Leaflet地图容器 -->
    <view id="windMap" class="wind-map"></view>
    
    <!-- 预报时次控制 - 独立定位 -->
    <view class="forecast-controls-independent">
      <view class="forecast-controls">
        <button @click="previousForecast" :class="{'nav-btn': true, 'disabled': currentForecastIndex <= 0}">上一小时</button>
        <text class="forecast-info">{{ String(currentForecastIndex + 1).padStart(3, '0') }}/120</text>
        <button @click="nextForecast" :class="{'nav-btn': true, 'disabled': currentForecastIndex >= 119}">下一小时</button>
      </view>
    </view>
    
    <!-- 控制面板容器 -->
    <view class="control-panel-wrapper">
      <!-- 收缩展开按钮 -->
      <view class="toggle-btn" :class="{ 'active': isPanelExpanded }" @click="togglePanel">
        <view class="menu-icon">
          <view class="menu-line" v-for="i in 3" :key="i"></view>
        </view>
      </view>
      
      <!-- 控制面板 -->
      <view class="control-panel" :class="{ 'collapsed': !isPanelExpanded }">
      <!-- 日期和时段选择 -->
      <view class="control-item">
        <text class="control-label">预报日期</text>
        <picker 
          mode="date" 
          :value="selectedDate" 
          @change="onDateChange"
          class="date-picker"
        >
          <view class="picker-text">{{ selectedDate }}</view>
        </picker>
      </view>
      
      <view class="control-item">
        <text class="control-label">预报时段</text>
        <picker 
          :value="currentTimeIndex" 
          :range="timeOptions" 
          range-key="label"
          @change="onTimeChange"
          class="time-picker"
        >
          <view class="picker-text">{{ timeOptions[currentTimeIndex].label }}</view>
        </picker>
      </view>
      
      <!-- 图层控制 -->
      <view class="control-item">
        <text class="control-label">图层显示</text>
        <view class="layer-controls">
          <view class="layer-item">
            <switch :checked="showWindField" @change="toggleWindField" />
            <text class="layer-text">风场</text>
          </view>
          <view class="layer-item">
            <switch :checked="showTemperature" @change="toggleTemperature" />
            <text class="layer-text">温度等值线</text>
          </view>
          <view class="layer-item">
            <switch :checked="showRainfall" @change="toggleRainfall" />
            <text class="layer-text">降雨等值面</text>
          </view>
        </view>
      </view>
      
      <!-- 温度图例已移至下方轮播图例中 -->
      
      <!-- 底图切换 -->
      <view class="control-item">
        <text class="control-label">底图类型</text>
        <picker 
          :value="currentBasemapIndex" 
          :range="basemapOptions" 
          range-key="name"
          @change="onBasemapChange"
          class="basemap-picker"
        >
          <view class="picker-text">{{ basemapOptions[currentBasemapIndex].name }}</view>
        </picker>
      </view>
      
      <view class="control-item">
        <text class="control-label">风场密度</text>
        <slider 
          :value="windDensity" 
          min="0.1" 
          max="2" 
          step="0.1"
          @change="onDensityChange"
          class="control-slider"
        />
        <text class="control-value">{{ windDensity.toFixed(1) }}</text>
      </view>
      
      <view class="control-item">
        <text class="control-label">箭头大小</text>
        <slider 
          :value="arrowScale" 
          min="0.5" 
          max="3" 
          step="0.1"
          @change="onScaleChange"
          class="control-slider"
        />
        <text class="control-value">{{ arrowScale.toFixed(1) }}</text>
      </view>
      
      <view class="control-item">
        <text class="control-label">动画速度</text>
        <slider 
          :value="animationSpeed" 
          min="0" 
          max="2" 
          step="0.1"
          @change="onSpeedChange"
          class="control-slider"
        />
        <text class="control-value">{{ animationSpeed.toFixed(1) }}</text>
      </view>
      
      <view class="control-buttons">
        <button @click="toggleAnimation" class="control-btn">
          {{ isAnimating ? '暂停动画' : '开始动画' }}
        </button>
        <button @click="refreshWindField" class="control-btn">刷新风场</button>
      </view>
    </view>
    </view>
        <!-- 图例滑动轮播 -->
    <view class="legend">
      <view class="legend-header">
        <text class="legend-title">{{ currentLegendIndex === 0 ? '风速 (m/s)' : '温度 (°C)' }}</text>
      </view>
      
      <view 
        class="legend-swiper"
        @touchstart="handleTouchStart"
        @touchmove="handleTouchMove"
        @touchend="handleTouchEnd"
        :style="{ transform: `translateX(${swipeOffset}%)` }"
      >
        <!-- 风速图例 -->
        <view class="legend-slide">
          <view class="legend-items">
            <view class="legend-item" v-for="item in legendItems" :key="item.speed">
              <view class="legend-color" :style="{ backgroundColor: item.color }"></view>
              <text class="legend-text">{{ item.speed }}</text>
            </view>
          </view>
        </view>
        
        <!-- 温度图例 -->
        <view class="legend-slide">
          <view class="legend-items">
            <view class="legend-item" v-for="item in temperatureLegend" :key="item.label">
              <view class="legend-color" :style="{ backgroundColor: item.color }"></view>
              <text class="legend-text">{{ item.label }}</text>
            </view>
          </view>
        </view>
      </view>
      
      <!-- 轮播指示器 -->
      <view class="legend-indicators">
        <view 
          v-for="(indicator, index) in 2" 
          :key="index"
          class="indicator" 
          :class="{ active: currentLegendIndex === index }"
          @click="currentLegendIndex = index"
        ></view>
      </view>
    </view>
  </view>
</template>

<script setup>
import { ref, onMounted, onUnmounted, nextTick } from 'vue'
import { getAllWindFieldPoints } from '@/data/windFieldPoints.js'
import { CDN_BASE_URL, API_BASE_URL } from '@/config/api.js'

// 控制面板展开收缩状态
const isPanelExpanded = ref(true)

// 图例轮播状态
const currentLegendIndex = ref(0) // 0: 风速, 1: 温度

// 触摸事件处理和滑动动画
const startX = ref(0)
const moveX = ref(0)
const isMoving = ref(false)
const swipeOffset = ref(0) // 初始位置

// 触摸开始
const handleTouchStart = (e) => {
  startX.value = e.touches[0].clientX
  isMoving.value = true
}

// 触摸移动 - 实时更新滑动位置
const handleTouchMove = (e) => {
  if (!isMoving.value) return
  moveX.value = e.touches[0].clientX
  const diff = moveX.value - startX.value
  // 计算实际的滑动偏移，但限制在-100%到0%之间
  swipeOffset.value = Math.max(-100, Math.min(0, -currentLegendIndex.value * 100 + diff * 100 / 300))
}

// 触摸结束 - 确定最终位置
const handleTouchEnd = () => {
  if (!isMoving.value) return
  
  const diff = moveX.value - startX.value
  // 如果滑动距离超过屏幕宽度的1/3，则切换到下一个/上一个
  if (diff > 100) {
    currentLegendIndex.value = Math.max(0, currentLegendIndex.value - 1)
  } else if (diff < -100) {
    currentLegendIndex.value = Math.min(1, currentLegendIndex.value + 1)
  }
  
  // 重置滑动偏移
  swipeOffset.value = -currentLegendIndex.value * 100
  isMoving.value = false
}

// 切换面板展开收缩
const togglePanel = () => {
  isPanelExpanded.value = !isPanelExpanded.value
}

// 天地图配置
const Tiandi = {
  TK: '324ecd6881be3d4e5c5439de4c164e92',
  P: '&style=default&tilematrixset=w&Service=WMTS&Request=GetTile&Version=1.0.0&Format=tiles&TileMatrix={z}&TileCol={x}&TileRow={y}&tk=',
  // 天地图 - 街道图
  VEC: 'http://t0.tianditu.gov.cn/vec_w/wmts?layer=vec',
  CVA: 'http://t0.tianditu.gov.cn/cva_w/wmts?layer=cva',
  // 天地图 - 影像图
  IMG: 'http://t0.tianditu.gov.cn/img_w/wmts?layer=img',
  CIA: 'http://t0.tianditu.gov.cn/cia_w/wmts?layer=cia',
  // 天地图 - 地形图
  TER: 'http://t0.tianditu.gov.cn/ter_w/wmts?layer=ter',
  CTA: 'http://t0.tianditu.gov.cn/cta_w/wmts?layer=cta'
}
const urlSuffix = `${Tiandi.P}${Tiandi.TK}`

// Props
const props = defineProps({
  centerLat: {
    type: Number,
    default: 41.8
  },
  centerLng: {
    type: Number,
    default: 123.4
  },
  zoom: {
    type: Number,
    default: 7
  }
})

// 日期和时段选择
const selectedDate = ref('2025-10-30')
const timeOptions = ref([
  { value: '00z', label: '00时' },
  { value: '06z', label: '06时' },
  { value: '12z', label: '12时' },
  { value: '18z', label: '18时' }
])
const currentTimeIndex = ref(0)

// 预报时次控制
const currentForecastIndex = ref(0) // 0-119 对应 f001-f120
const currentForecastHour = ref(1) // 当前预报小时数

// 图层控制
const showWindField = ref(true)
const showTemperature = ref(true)
const showRainfall = ref(true)

// 温度图例数据 - 高对比度配色方案
const temperatureLegend = ref([
  { label: '极热 35°C+', color: '#FF0000' },    // 纯红色
  { label: '很热 30°C+', color: '#FF4500' },    // 橙红色
  { label: '热 25°C+', color: '#FF8C00' },      // 深橙色
  { label: '温暖 20°C+', color: '#FFD700' },    // 金色
  { label: '舒适 15°C+', color: '#FFFF00' },    // 纯黄色
  { label: '凉爽 10°C+', color: '#00FFFF' },    // 青色
  { label: '冷 5°C+', color: '#0080FF' },       // 亮蓝色
  { label: '很冷 0°C+', color: '#0000FF' },     // 纯蓝色
  { label: '寒冷 -5°C+', color: '#8000FF' },    // 紫蓝色
  { label: '很寒冷 -10°C+', color: '#FF00FF' }, // 洋红色
  { label: '极寒 -10°C以下', color: '#800080' } // 紫色
])

// 底图选项
const basemapOptions = ref([
  { name: '街道图', type: 'street', baseUrl: Tiandi.VEC, labelUrl: Tiandi.CVA },
  { name: '影像图', type: 'satellite', baseUrl: Tiandi.IMG, labelUrl: Tiandi.CIA },
  { name: '地形图', type: 'terrain', baseUrl: Tiandi.TER, labelUrl: Tiandi.CTA }
])
const currentBasemapIndex = ref(2) // 默认选择地形图

// 响应式数据
const windDensity = ref(2.0) // 风场密度
const arrowScale = ref(2.2) // 箭头大小
const animationSpeed = ref(2.0) // 动画速度
const isAnimating = ref(true)

// 地图和Canvas相关
let map = null
let windCanvas = null
let windContext = null
let animationFrame = null
let windData = []
let particles = []
let currentBaseLayers = [] // 存储当前底图图层
let temperatureLayer = null // 温度等值线图层
let rainfallLayer = null // 降雨等值面图层

// 图例数据
const legendItems = ref([
  { speed: '0-2', color: '#3498db' },
  { speed: '2-5', color: '#2ecc71' },
  { speed: '5-8', color: '#f1c40f' },
  { speed: '8-12', color: '#e67e22' },
  { speed: '12+', color: '#e74c3c' }
])

// CDN数据获取
const fetchGeoJSONData = async (type, date, time, forecastHour) => {
  try {
    const baseUrl = `${CDN_BASE_URL}/rainfall/A_OA_data/GFS/nc_batch`
    const dateStr = date.replace(/-/g, '/')
    const forecastStr = `f${String(forecastHour).padStart(3, '0')}`
    const dateTimeStr = `${date.replace(/-/g, '')}_${time}`
    
    let url
    if (type === 'temperature') {
      url = `${baseUrl}/temperature/${dateStr}/${time}/gfs_${dateTimeStr}_china_120h_temp_${forecastStr}.geojson`
    } else if (type === 'rainfall') {
      url = `${baseUrl}/geojson/${dateStr}/${time}/gfs_${dateTimeStr}_china_120h_${forecastStr}.geojson`
    }
    
    console.log('Fetching data from:', url)
    const response = await fetch(url)
    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`)
    }
    return await response.json()
  } catch (error) {
    console.error(`Failed to fetch ${type} data:`, error)
    return null
  }
}

// 日期选择处理
const onDateChange = (e) => {
  selectedDate.value = e.detail.value
  loadWeatherData()
}

// 时段选择处理
const onTimeChange = (e) => {
  currentTimeIndex.value = e.detail.value
  loadWeatherData()
}

// 预报时次控制
const previousForecast = () => {
  if (currentForecastIndex.value > 0) {
    currentForecastIndex.value--
    currentForecastHour.value = currentForecastIndex.value + 1
    console.log(`切换到预报时次: ${currentForecastHour.value}小时`)
    
    // 停止当前动画
    if (animationFrame) {
      cancelAnimationFrame(animationFrame)
      animationFrame = null
    }
    isAnimating.value = false
    
    // 清空当前粒子
    particles = []
    if (windCanvas && windContext) {
      windContext.clearRect(0, 0, windCanvas.width, windCanvas.height)
    }
    
    // 重新加载天气数据（包括风场）
    loadWeatherData()
  }
}

const nextForecast = () => {
  console.log('=== 点击下一页按钮 ===')
  console.log('当前预报时次索引:', currentForecastIndex.value)
  console.log('当前showWindField状态:', showWindField.value)
  
  if (currentForecastIndex.value < 119) {
    currentForecastIndex.value++
    currentForecastHour.value = currentForecastIndex.value + 1
    console.log(`切换到预报时次: ${currentForecastHour.value}小时 (索引: ${currentForecastIndex.value})`)
    
    // 停止当前动画
    if (animationFrame) {
      console.log('停止当前动画')
      cancelAnimationFrame(animationFrame)
      animationFrame = null
    }
    isAnimating.value = false
    
    // 清空当前粒子
    particles = []
    if (windCanvas && windContext) {
      console.log('清空Canvas')
      windContext.clearRect(0, 0, windCanvas.width, windCanvas.height)
    }
    
    console.log('开始重新加载天气数据...')
    // 重新加载天气数据（包括风场）
    loadWeatherData()
  } else {
    console.log('已经是最后一个预报时次')
  }
}

// 图层控制
const toggleWindField = (e) => {
  showWindField.value = e.detail.value
  if (showWindField.value) {
    startAnimation()
  } else {
    if (windCanvas) {
      windContext.clearRect(0, 0, windCanvas.width, windCanvas.height)
    }
  }
}

const toggleTemperature = (e) => {
  showTemperature.value = e.detail.value
  if (temperatureLayer) {
    if (showTemperature.value) {
      temperatureLayer.addTo(map)
    } else {
      map.removeLayer(temperatureLayer)
    }
  }
}

const toggleRainfall = (e) => {
  showRainfall.value = e.detail.value
  if (rainfallLayer) {
    if (showRainfall.value) {
      rainfallLayer.addTo(map)
    } else {
      map.removeLayer(rainfallLayer)
    }
  }
}

// 加载天气数据
const loadWeatherData = async () => {
  console.log('=== loadWeatherData 开始执行 ===')
  const currentTime = timeOptions.value[currentTimeIndex.value].value
  const forecastHour = currentForecastIndex.value + 1
  
  console.log('当前时间:', currentTime)
  console.log('预报时次:', forecastHour)
  console.log('showWindField状态:', showWindField.value)
  
  // 加载温度等值线数据
  if (showTemperature.value) {
    console.log('开始加载温度数据...')
    const tempData = await fetchGeoJSONData('temperature', selectedDate.value, currentTime, forecastHour)
    if (tempData) {
      addTemperatureLayer(tempData)
    }
  }
  
  // 加载降雨等值面数据
  if (showRainfall.value) {
    console.log('开始加载降雨数据...')
    const rainData = await fetchGeoJSONData('rainfall', selectedDate.value, currentTime, forecastHour)
    if (rainData) {
      addRainfallLayer(rainData)
    }
  }
  
  // 加载风场数据
  if (showWindField.value) {
    console.log('开始加载风场数据...')
    await generateWindData()
    console.log('风场数据加载完成')
  } else {
    console.log('showWindField为false，跳过风场数据加载')
  }
  
  console.log('=== loadWeatherData 执行完成 ===')
}

// 添加温度等值线图层
const addTemperatureLayer = (geoJsonData) => {
  // 移除现有温度图层
  if (temperatureLayer && map.hasLayer(temperatureLayer)) {
    map.removeLayer(temperatureLayer)
  }
  
  if (!geoJsonData || !geoJsonData.features || geoJsonData.features.length === 0) {
    console.warn('No temperature data available')
    return
  }
  
  console.log('Temperature data bounds:', geoJsonData.features.length, 'features')
  
  temperatureLayer = L.geoJSON(geoJsonData, {
    style: (feature) => {
      const temperature = feature.properties.level || 0
      
      // 美观的自然渐变配色方案 - 模拟热力图效果
      let color = '#1e3a8a'  // 默认深蓝色
      let shadowColor = '#0f172a'  // 阴影色
      
      if (temperature >= 40) {
        color = '#dc2626'      // 深红色 - 极热
        shadowColor = '#7f1d1d'
      } else if (temperature >= 35) {
        color = '#ea580c'      // 橙红色 - 很热  
        shadowColor = '#9a3412'
      } else if (temperature >= 30) {
        color = '#f59e0b'      // 琥珀色 - 热
        shadowColor = '#92400e'
      } else if (temperature >= 25) {
        color = '#eab308'      // 黄色 - 温暖
        shadowColor = '#a16207'
      } else if (temperature >= 20) {
        color = '#84cc16'      // 青柠色 - 舒适
        shadowColor = '#4d7c0f'
      } else if (temperature >= 15) {
        color = '#22c55e'      // 绿色 - 宜人
        shadowColor = '#15803d'
      } else if (temperature >= 10) {
        color = '#06b6d4'      // 青色 - 凉爽
        shadowColor = '#0e7490'
      } else if (temperature >= 5) {
        color = '#3b82f6'      // 蓝色 - 冷
        shadowColor = '#1d4ed8'
      } else if (temperature >= 0) {
        color = '#6366f1'      // 靛蓝色 - 很冷
        shadowColor = '#4338ca'
      } else if (temperature >= -5) {
        color = '#8b5cf6'      // 紫色 - 寒冷
        shadowColor = '#7c3aed'
      } else if (temperature >= -10) {
        color = '#a855f7'      // 紫罗兰色 - 很寒冷
        shadowColor = '#9333ea'
      } else {
        color = '#c084fc'      // 淡紫色 - 极寒
        shadowColor = '#a855f7'
      }
      
      // 根据温度调整线条粗细，创造层次感
      let weight = 3
      if (Math.abs(temperature) >= 30) weight = 4  // 极端温度稍粗
      if (Math.abs(temperature) >= 35) weight = 5  // 非常极端的温度更粗
      
      return {
        color: color,
        weight: weight,
        opacity: 0.85,
        lineCap: 'round',
        lineJoin: 'round',
        smoothFactor: 0.5,
        // 添加渐变和发光效果的CSS类
        className: `temperature-line temp-${Math.floor(temperature / 5) * 5}`,
        // 添加阴影效果
        shadowColor: shadowColor,
        shadowWeight: weight + 1,
        shadowOpacity: 0.3
      }
    },
    onEachFeature: (feature, layer) => {
      const temp = feature.properties.temperature || `${feature.properties.level}°C`
      layer.bindPopup(`温度: ${temp}`)
    }
  })
  
  if (showTemperature.value) {
    temperatureLayer.addTo(map)
  }
}

// 添加降雨等值面图层
const addRainfallLayer = (geoJsonData) => {
  // 移除现有降雨图层
  if (rainfallLayer && map.hasLayer(rainfallLayer)) {
    map.removeLayer(rainfallLayer)
  }
  
  if (!geoJsonData || !geoJsonData.features || geoJsonData.features.length === 0) {
    console.warn('No rainfall data available')
    return
  }
  
  console.log('Rainfall data bounds:', geoJsonData.features.length, 'features')
  
  rainfallLayer = L.geoJSON(geoJsonData, {
    style: (feature) => {
      const level = feature.properties.level || 0
      const color = feature.properties.color || '#FFFFFF'
      
      // 根据降雨量级别设置不同的透明度和颜色
      let fillOpacity = 0.1
      if (level > 0.1) fillOpacity = 0.3
      if (level > 1) fillOpacity = 0.4
      if (level > 5) fillOpacity = 0.5
      if (level > 10) fillOpacity = 0.6
      if (level > 25) fillOpacity = 0.7
      
      return {
        fillColor: color,
        weight: 0.5,
        opacity: 0.8,
        color: color,
        fillOpacity: fillOpacity
      }
    },
    onEachFeature: (feature, layer) => {
      const level = feature.properties.level
      if (level !== undefined) {
        layer.bindPopup(`降雨量: ${level}mm`)
      }
    }
  })
  
  if (showRainfall.value) {
    rainfallLayer.addTo(map)
  }
}

// 风场粒子类
class WindParticle {
  constructor(x, y, vx, vy, life = 80) {
    this.x = x
    this.y = y
    this.originX = x // 记录起始位置
    this.originY = y
    this.vx = vx
    this.vy = vy
    this.life = life
    this.maxLife = life
    this.trail = []
    this.size = Math.random() * 1.5 + 0.8
    this.maxDistance = 40 + Math.random() * 20 // 最大飘动距离 60-100px
  }
  
  update() {
    this.x += this.vx * animationSpeed.value * 0.1 // 进一步降低移动速度
    this.y += this.vy * animationSpeed.value * 0.1
    this.life--
    
    // 检查是否超出最大飘动距离
    const distance = Math.sqrt(
      Math.pow(this.x - this.originX, 2) + Math.pow(this.y - this.originY, 2)
    )
    
    // 如果超出最大距离，重置粒子位置
    if (distance > this.maxDistance) {
      this.resetPosition()
    }
    
    // 添加轨迹点
    this.trail.push({ x: this.x, y: this.y })
    if (this.trail.length > 8) { // 减少轨迹长度
      this.trail.shift()
    }
  }
  
  resetPosition() {
    // 重置到起始位置附近
    this.x = this.originX + (Math.random() - 0.5) * 20
    this.y = this.originY + (Math.random() - 0.5) * 20
    this.life = this.maxLife // 重置生命周期
    this.trail = [] // 清空轨迹
  }
  
  draw(ctx) {
    if (this.life <= 0 || this.trail.length < 2) return
    
    const alpha = Math.min(this.life / this.maxLife, 0.8)
    
    // 绘制流线轨迹
    ctx.globalAlpha = alpha * 0.7
    ctx.beginPath()
    ctx.moveTo(this.trail[0].x, this.trail[0].y)
    
    for (let i = 1; i < this.trail.length; i++) {
      const segmentAlpha = (i / this.trail.length) * alpha
      ctx.globalAlpha = segmentAlpha * 0.7
      ctx.lineTo(this.trail[i].x, this.trail[i].y)
    }
    
    ctx.strokeStyle = this.getSpeedColor()
    ctx.lineWidth = this.size * arrowScale.value
    ctx.lineCap = 'round'
    ctx.stroke()
    
    // 绘制粒子头部（箭头效果）
    if (this.trail.length >= 2) {
      const current = this.trail[this.trail.length - 1]
      const previous = this.trail[this.trail.length - 2]
      const angle = Math.atan2(current.y - previous.y, current.x - previous.x)
      
      ctx.globalAlpha = alpha * 0.9
      ctx.fillStyle = this.getSpeedColor()
      
      // 绘制箭头头部
      const headSize = this.size * arrowScale.value * 2.5
      ctx.beginPath()
      ctx.moveTo(current.x, current.y)
      ctx.lineTo(
        current.x - Math.cos(angle - 0.4) * headSize,
        current.y - Math.sin(angle - 0.4) * headSize
      )
      ctx.lineTo(
        current.x - Math.cos(angle + 0.4) * headSize,
        current.y - Math.sin(angle + 0.4) * headSize
      )
      ctx.closePath()
      ctx.fill()
    }
    
    ctx.globalAlpha = 1
  }
  
  getSpeedColor() {
    const speed = Math.sqrt(this.vx * this.vx + this.vy * this.vy)
    if (speed < 2) return '#3498db'
    if (speed < 5) return '#2ecc71'
    if (speed < 8) return '#f1c40f'
    if (speed < 12) return '#e67e22'
    return '#e74c3c'
  }
  
  isDead() {
    return false // 粒子不会死亡，只会重置位置
  }
}

// 底图切换处理
const onBasemapChange = (e) => {
  const index = e.detail.value
  currentBasemapIndex.value = index
  if (map) {
    addBasemap(index)
  }
}

// 初始化地图
const initMap = async () => {
  try {
    await loadLeaflet()
    
    // 创建地图 - 简化设置，统一所有图层的边界处理
    map = L.map('windMap', {
      center: [44.0, 125.0], // 东三省中心位置
      zoom: 6, // 适合东三省的缩放级别
      zoomControl: false, // 禁用缩放控件
      scrollWheelZoom: false, // 禁用滚轮缩放
      doubleClickZoom: false, // 禁用双击缩放
      touchZoom: false, // 禁用触摸缩放
      boxZoom: false, // 禁用框选缩放
      keyboard: false, // 禁用键盘缩放
      dragging: true // 保持拖拽功能
    })
    
    // 添加天地图底图（默认街道图）
    addBasemap(currentBasemapIndex.value)

    // 移除默认的attribution控件（包含乌克兰图标）
		map.attributionControl.remove()
    
    // 创建Canvas覆盖层
    createWindCanvas()
    
    // 生成风场数据
    await generateWindData()
    
    // 开始动画
    startAnimation()
    
  } catch (error) {
    console.error('地图初始化失败:', error)
  }
}

// 添加底图图层
const addBasemap = (index) => {
  // 移除现有底图图层
  currentBaseLayers.forEach(layer => {
    if (map && map.hasLayer(layer)) {
      map.removeLayer(layer)
    }
  })
  currentBaseLayers = []
  
  const basemap = basemapOptions.value[index]
  
  // 添加底图图层
  const baseLayer = L.tileLayer(`${basemap.baseUrl}${urlSuffix}`, {
    attribution: '© 天地图'
  })
  baseLayer.addTo(map)
  currentBaseLayers.push(baseLayer)
  
  // 添加标注图层
  const labelLayer = L.tileLayer(`${basemap.labelUrl}${urlSuffix}`, {
    attribution: '© 天地图'
  })
  labelLayer.addTo(map)
  currentBaseLayers.push(labelLayer)
}

// 动态加载Leaflet
const loadLeaflet = () => {
  return new Promise((resolve, reject) => {
    if (window.L) {
      resolve()
      return
    }
    
    // 加载CSS
    const link = document.createElement('link')
    link.rel = 'stylesheet'
    link.href = 'https://unpkg.com/leaflet@1.9.4/dist/leaflet.css'
    document.head.appendChild(link)
    
    // 加载JS
    const script = document.createElement('script')
    script.src = 'https://unpkg.com/leaflet@1.9.4/dist/leaflet.js'
    script.onload = resolve
    script.onerror = reject
    document.head.appendChild(script)
  })
}

// 创建Canvas覆盖层
const createWindCanvas = () => {
  const mapContainer = map.getContainer()
  const mapSize = map.getSize()
  
  // 创建Canvas元素
  windCanvas = document.createElement('canvas')
  windCanvas.width = mapSize.x
  windCanvas.height = mapSize.y
  windCanvas.style.position = 'absolute'
  windCanvas.style.top = '0'
  windCanvas.style.left = '0'
  windCanvas.style.pointerEvents = 'none'
  windCanvas.style.zIndex = '500'
  
  mapContainer.appendChild(windCanvas)
  windContext = windCanvas.getContext('2d')
  
  // 监听地图事件
  map.on('zoom', updateCanvasSize)
  map.on('move', updateCanvasSize)
  map.on('resize', updateCanvasSize)
}

// 更新Canvas尺寸和坐标
const updateCanvasSize = async () => {
  if (!windCanvas || !map) return
  
  const mapSize = map.getSize()
  windCanvas.width = mapSize.x
  windCanvas.height = mapSize.y
  
  // 重新生成风场数据以适应新的地图视图
  await generateWindData()
}

// 从API获取风场数据
const fetchWindFieldData = async () => {
  try {
    // 构建风场数据API URL - 使用与温度和降雨数据相同的路径格式
    const baseUrl = `${CDN_BASE_URL}/rainfall/A_OA_data/GFS/nc_batch`
    const dateStr = selectedDate.value.replace(/-/g, '/')
    const time = timeOptions.value[currentTimeIndex.value].value
    const forecastStr = `f${String(currentForecastIndex.value).padStart(3, '0')}`
    const dateTimeStr = `${selectedDate.value.replace(/-/g, '')}_${time}`
    
    const url = `${baseUrl}/wind_field/${dateStr}/${time}/gfs_${dateTimeStr}_china_120h_${forecastStr}.json`
    
    console.log('=== fetchWindFieldData 开始 ===')
    console.log('selectedDate:', selectedDate.value)
    console.log('dateStr:', dateStr)
    console.log('currentTimeIndex:', currentTimeIndex.value)
    console.log('time:', time)
    console.log('currentForecastIndex:', currentForecastIndex.value)
    console.log('forecastStr:', forecastStr)
    console.log('dateTimeStr:', dateTimeStr)
    console.log('构建的URL:', url)
    
    // 添加超时和错误处理
    const controller = new AbortController()
    const timeoutId = setTimeout(() => controller.abort(), 10000) // 10秒超时
    
    const response = await fetch(url, {
      method: 'GET',
      headers: {
        'Accept': 'application/json',
        'Content-Type': 'application/json'
      },
      signal: controller.signal
    })
    
    clearTimeout(timeoutId)
    
    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`)
    }
    
    const data = await response.json()
    console.log('风场数据获取成功，数据点数量:', data.particles ? data.particles.length : 0)
    console.log('API返回的数据结构:', Object.keys(data))
    
    return data
  } catch (error) {
    if (error.name === 'AbortError') {
      console.error('获取风场数据超时')
    } else {
      console.error('获取风场数据失败:', error)
    }
    return null
  }
}

// 处理风场数据并生成粒子
const generateWindData = async () => {
  windData = []
  
  try {
    // 从API获取风场数据
    const apiData = await fetchWindFieldData()
    
    if (apiData && apiData.particles && Array.isArray(apiData.particles)) {
      console.log(`API返回了 ${apiData.particles.length} 个风场数据点`)
      
      // 调试：检查第一个粒子的数据结构
      if (apiData.particles.length > 0) {
        console.log('第一个粒子的数据结构:', apiData.particles[0])
        console.log('粒子字段名:', Object.keys(apiData.particles[0]))
      }
      
      // 使用API返回的particles数据
      apiData.particles.forEach((particle, index) => {
        // 调试：检查前几个粒子的数据
        if (index < 3) {
          console.log(`粒子 ${index}:`, particle)
        }
        
        // 检查数据结构类型
        if (particle.lat !== undefined && particle.lng !== undefined) {
          // 类型1：包含地理坐标的数据（需要转换）
          const lat = particle.lat
          const lng = particle.lng
          
          if (typeof lat === 'number' && typeof lng === 'number') {
            // 将地理坐标转换为屏幕坐标
            const screenPoint = map.latLngToContainerPoint([lat, lng])
            
            const u = particle.u || 0 // u分量（东西方向）
            const v = particle.v || 0 // v分量（南北方向）
            const speed = Math.sqrt(u * u + v * v)
            
            windData.push({
              x: screenPoint.x,
              y: screenPoint.y,
              vx: u * 0.5, // 调整速度系数以适合动画
              vy: v * 0.5,
              speed: speed,
              direction: Math.atan2(v, u) * 180 / Math.PI,
              lat: lat,
              lng: lng
            })
          }
        } else if (particle.x !== undefined && particle.y !== undefined) {
          // 类型2：已经是屏幕坐标的数据（直接使用）
          const x = particle.x
          const y = particle.y
          
          if (typeof x === 'number' && typeof y === 'number') {
            const vx = particle.vx || 0
            const vy = particle.vy || 0
            const speed = particle.speed || Math.sqrt(vx * vx + vy * vy)
            const direction = particle.direction || Math.atan2(vy, vx) * 180 / Math.PI
            
            windData.push({
              x: x,
              y: y,
              vx: vx,
              vy: vy,
              speed: speed,
              direction: direction,
              lat: null, // 屏幕坐标数据没有地理坐标
              lng: null
            })
          }
        }
      })
      
      console.log(`处理了 ${windData.length} 个有效风场数据点`)
      
      // 生成粒子
      generateParticles()
      
      // 确保动画启动
      if (windData.length > 0 && showWindField.value) {
        console.log('启动风场动画，当前showWindField状态:', showWindField.value)
        console.log('当前windData长度:', windData.length)
        console.log('当前particles长度:', particles.length)
        startAnimation()
      } else {
        console.warn('无法启动动画 - windData长度:', windData.length, 'showWindField:', showWindField.value)
      }
    } else {
      console.error('API返回的风场数据格式不正确或为空')
      windData = []
    }
  } catch (error) {
    console.error('处理风场数据时发生错误:', error)
    windData = []
  }
}

// 生成粒子
const generateParticles = () => {
  particles = []
  const particleCount = Math.floor(windData.length * windDensity.value * 1.5) // 适度减少粒子数量
  
  for (let i = 0; i < particleCount; i++) {
    const windPoint = windData[Math.floor(Math.random() * windData.length)]
    if (windPoint) {
      const particle = new WindParticle(
        windPoint.x + (Math.random() - 0.5) * 30, // 减少初始散布范围
        windPoint.y + (Math.random() - 0.5) * 30,
        windPoint.vx,
        windPoint.vy,
        Math.floor(Math.random() * 60) + 60 // 适中的生命周期
      )
      particles.push(particle)
    }
  }
}

// 绘制风场粒子
const drawWindField = () => {
  if (!windContext || !particles.length) return
  
  windContext.clearRect(0, 0, windCanvas.width, windCanvas.height)
  
  // 只绘制动态粒子，移除静态箭头
  particles.forEach(particle => {
    particle.draw(windContext)
  })
}

// 根据风速获取颜色
const getWindColor = (speed) => {
  if (speed < 2) return '#3498db'
  if (speed < 5) return '#2ecc71'
  if (speed < 8) return '#f1c40f'
  if (speed < 12) return '#e67e22'
  return '#e74c3c'
}

// 动画循环
const animate = () => {
  if (!isAnimating.value || !windCanvas || !windContext) {
    console.log('动画已停止或Canvas未初始化')
    return
  }
  
  try {
    // 更新粒子
    particles.forEach(particle => {
      particle.update()
    })
    
    // 由于粒子不再死亡，只需要检查数量是否足够
    const targetCount = Math.floor(windData.length * windDensity.value * 1.5)
    
    // 如果粒子数量不足，补充新粒子
    while (particles.length < targetCount && windData.length > 0) {
      const windPoint = windData[Math.floor(Math.random() * windData.length)]
      if (windPoint) {
        const particle = new WindParticle(
          windPoint.x + (Math.random() - 0.5) * 30,
          windPoint.y + (Math.random() - 0.5) * 30,
          windPoint.vx,
          windPoint.vy,
          Math.floor(Math.random() * 60) + 60
        )
        particles.push(particle)
      }
    }
    
    // 如果粒子过多，移除多余的
    if (particles.length > targetCount) {
      particles = particles.slice(0, targetCount)
    }
    
    // 绘制
    drawWindField()
    
    // 使用兼容性更好的方式请求下一帧
    animationFrame = (window.requestAnimationFrame || 
                     window.webkitRequestAnimationFrame || 
                     window.mozRequestAnimationFrame || 
                     function(callback) { 
                       return setTimeout(callback, 1000 / 60) 
                     })(animate)
  } catch (error) {
    console.error('动画循环中发生错误:', error)
    isAnimating.value = false
  }
}

// 开始动画
const startAnimation = () => {
  console.log('开始启动风场动画')
  
  // 停止之前的动画
  if (animationFrame) {
    cancelAnimationFrame(animationFrame)
    animationFrame = null
  }
  
  // 确保有风场数据和粒子
  if (windData.length === 0) {
    console.warn('没有风场数据，无法启动动画')
    return
  }
  
  if (particles.length === 0) {
    console.log('生成粒子用于动画')
    generateParticles()
  }
  
  // 设置动画状态
  isAnimating.value = true
  console.log('动画状态已设置为true，开始动画循环')
  
  // 开始动画循环
  animate()
}

// 控制事件处理
const onDensityChange = (e) => {
  windDensity.value = e.detail.value
  generateParticles()
}

const onScaleChange = (e) => {
  arrowScale.value = e.detail.value
}

const onSpeedChange = (e) => {
  animationSpeed.value = e.detail.value
}

const toggleAnimation = () => {
  isAnimating.value = !isAnimating.value
  if (isAnimating.value) {
    startAnimation()
  }
}

const refreshWindField = async () => {
  await generateWindData()
}

const getCoordinate = async (stcd) => {
  if (stcd) {
    try {
      console.log('正在调用水库详情API:', `/api/get_reservoir_by_stcd?basin=${stcd}`)
      const response = await uni.request({
        url: `${API_BASE_URL}/api/get_reservoir_by_stcd?basin=${stcd}`,
        method: 'GET'
      })
      
      console.log('水库详情API响应:', response)
      if (response.data.success) {
        const reservoirData = response.data.data
        
        // 设置地图相关数据
        const point = {
          lon: reservoirData.outlet_coordinates.longitude,
          lat: reservoirData.outlet_coordinates.latitude,
          name: reservoirData.stnm
        }
        drawMakerOnCenter(point)
      }
    } catch (error) {
      console.error('获取水库详情失败:', error)
    }
  }
}

// 在省会中心绘制 maker
const drawMakerOnCenter = (position) => {
  const markersLayer = L.layerGroup()
  const markerIcon = L.divIcon({
    html: `<div class="marker-icon"></div>`,
  });
  const { lon, lat } = position
  L.marker([lat, lon], { icon: markerIcon }).bindPopup(position.name).addTo(markersLayer);
  markersLayer.addTo(map)
}

// 生命周期
onMounted(async () => {
  const pages = getCurrentPages()
  const currentPage = pages[pages.length - 1]
  const options = currentPage.options || {}
  const stcd = options.stcd || ''

  await nextTick()

  initMap()
  // 初始加载天气数据
  setTimeout(() => {
    loadWeatherData()
    getCoordinate(stcd)
  }, 1000) // 等待地图初始化完成
})

onUnmounted(() => {
  if (animationFrame) {
    cancelAnimationFrame(animationFrame)
  }
  if (map) {
    map.remove()
  }
})
</script>

<style scoped>
.wind-field-container {
  position: relative;
  width: 100%;
  height: calc(100vh - (22rpx + env(safe-area-inset-top))); /* 从100vh调整为70vh，减少地图高度 */
  background: #f5f7fa;
}

:deep(div.leaflet-marker-icon) {
  background-color: transparent;
  border: none;
  margin-top: -10px !important;
  margin-left: -10px !important;
  width: 20px !important;
  height: 20px !important;
}

:deep(.marker-icon) {
  position: relative;
  width: 20px;
  height: 20px;
  background: rgba(0, 80, 255, 1);
  border-radius: 50%;
}

:deep(.marker-icon::after) {
  content: '';
  position: absolute;
  top: -8px;
  left: -8px;
  width: 36px;
  height: 36px;
  background-color: rgba(0, 80, 255, 1);
  border-radius: 50%;
  animation: breathing 2s ease-in-out infinite;
}

@keyframes breathing {
  0% {
    transform: scale(0.5);
    opacity: 1;
  }
  80% {
    transform: scale(1.2);
    opacity: 0.4;
  }
  90% {
    transform: scale(1.4);
    opacity: 0.2;
  }
  100% {
    transform: scale(1.6);
    opacity: 0;
  }
}


:deep(.marker-popup) {
  position: absolute;
  bottom: 0;
  left: 50%;
  transform: translateX(-50%);
  background: rgba(0, 80, 255, 0.8);
  color: #fff;
  padding: 5px 10px;
  border-radius: 5px;
}


.wind-map {
  width: 100%;
  height: 100%;
}

.forecast-controls-independent {
  position: absolute;
  bottom: 0rpx;
  right: 0rpx;
  background: transparent;
  border-radius: 16rpx;
  padding: 20rpx;
  z-index: 1003;
  width: 100%;
}

.control-panel-wrapper {
  position: absolute;
  top: 30rpx;
  right: 20rpx;
  z-index: 501;
  padding-top: 80rpx;
}

.toggle-btn {
  position: absolute;
  top: 20rpx;
  right: 20rpx;
  width: 80rpx;
  height: 80rpx;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(255, 255, 255, 0.95);
  backdrop-filter: blur(10rpx);
  border-radius: 12rpx;
  border: 1rpx solid rgba(255, 255, 255, 0.8);
  cursor: pointer;
  user-select: none;
  box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.1);
  transition: all 0.3s ease;
  z-index: 502;
}

.toggle-btn:active {
  background: rgba(245, 245, 245, 0.95);
}

.menu-icon {
  width: 44rpx;
  height: 36rpx;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  align-items: center;
  transition: transform 0.3s ease;
}

.toggle-btn.active .menu-icon {
  transform: rotate(90deg);
}

.menu-line {
  width: 100%;
  height: 6rpx;
  background: #2c3e50;
  border-radius: 3rpx;
  transition: all 0.3s ease;
}

.toggle-btn.active .menu-line:nth-child(1) {
  transform: translateY(15rpx) rotate(45deg);
}

.toggle-btn.active .menu-line:nth-child(2) {
  opacity: 0;
}

.toggle-btn.active .menu-line:nth-child(3) {
  transform: translateY(-15rpx) rotate(-45deg);
}

.control-panel {
  background: rgba(255, 255, 255, 0.95);
  backdrop-filter: blur(10rpx);
  border-radius: 16rpx;
  padding: 24rpx;
  box-shadow: 0 8rpx 32rpx rgba(0, 0, 0, 0.1);
  min-width: 320rpx;
  max-height: 80vh;
  overflow-y: auto;
  transition: all 0.3s ease;
  opacity: 1;
  transform: translateY(0);
}

.control-panel.collapsed {
  opacity: 0;
  transform: translateY(-20rpx);
  max-height: 0;
  padding: 0 24rpx;
  overflow: hidden;
  box-shadow: none;
}

.control-item {
  margin-bottom: 24rpx;
}

.control-label {
  display: block;
  font-size: 24rpx;
  color: #2c3e50;
  margin-bottom: 12rpx;
  font-weight: 500;
}

.picker-text {
  padding: 12rpx 16rpx;
  background: #f8f9fa;
  border-radius: 8rpx;
  border: 1rpx solid #e9ecef;
  font-size: 24rpx;
  color: #495057;
}

.forecast-controls {
  display: flex;
  align-items: center;
  gap: 12rpx;
  margin-top: 8rpx;
}

.nav-btn {
  width: 220rpx;
  padding: 12rpx 16rpx;
  background: rgba(0, 0, 0, 0.4);
  color: white;
  border: none;
  border-radius: 8rpx;
  font-size: 20rpx;
  font-weight: 500;
}

.nav-btn.disabled {
  background: rgba(0, 0, 0, 0.4);
  color: #666;
}

.forecast-info {
  font-size: 20rpx;
  color: #fff;
  text-align: center;
  flex: 1;
}

.layer-controls {
  display: flex;
  flex-direction: column;
  gap: 12rpx;
}

.layer-item {
  display: flex;
  align-items: center;
  gap: 12rpx;
}

.layer-text {
  font-size: 22rpx;
  color: #495057;
}

.control-slider {
  width: calc(100% - 4rpx);
  margin: 0rpx;
  margin-bottom: 8rpx;
}

.control-value {
  font-size: 22rpx;
  color: #7f8c8d;
  text-align: right;
  display: block;
}

.control-buttons {
  display: flex;
  gap: 12rpx;
  margin-top: 20rpx;
}

.control-btn {
  flex: 1;
  padding: 16rpx 20rpx;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  color: white;
  border: none;
  border-radius: 12rpx;
  font-size: 22rpx;
  font-weight: 500;
  transition: all 0.3s ease;
}

.control-btn:active {
  transform: scale(0.95);
}

.legend {
  position: absolute;
  bottom: 110rpx;
  left: 20rpx;
  background: rgba(0, 0, 0, 0.4);
  border-radius: 16rpx;
  padding: 20rpx;
  z-index: 501;
  width: 220rpx;
  overflow: hidden;
}

.legend-header {
  margin-bottom: 16rpx;
}

.legend-title {
  font-size: 24rpx;
  color: #fff;
  font-weight: 600;
  display: block;
}

.legend-swiper {
  display: flex;
  transition: transform 0.3s ease;
  width: 200%; /* 两个slide */
  user-select: none; /* 防止滑动时选中文本 */
  touch-action: pan-y; /* 优化触摸体验，允许垂直滚动 */
}

.legend-slide {
  width: 100%;
  flex-shrink: 0;
  height: 200rpx;
  overflow-y: auto;
}

/* 轮播指示器 */
.legend-indicators {
  display: flex;
  justify-content: center;
  gap: 8rpx;
  margin-top: 16rpx;
}

.indicator {
  width: 16rpx;
  height: 16rpx;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.3);
  transition: all 0.3s ease;
  cursor: pointer;
}

.indicator.active {
  background: rgba(255, 255, 255, 0.8);
  width: 32rpx;
  border-radius: 8rpx;
}

.legend-items {
  display: flex;
  flex-direction: column;
  gap: 8rpx;
}

.legend-items {
  display: flex;
  flex-direction: column;
  gap: 8rpx;
}

.legend-item {
  display: flex;
  align-items: center;
  gap: 12rpx;
}

.legend-color {
  width: 24rpx;
  height: 16rpx;
  border-radius: 4rpx;
}

.legend-text {
  font-size: 20rpx;
  color: #fff;
}

/* 温度线描边效果 */
.temperature-line-with-outline {
  filter: drop-shadow(0 0 2px rgba(255, 255, 255, 0.8)) 
          drop-shadow(0 0 4px rgba(0, 0, 0, 0.6));
}

/* 温度线基础样式 - 保持配色方案 */
.temperature-line {
  opacity: 0.85;
  transition: opacity 0.3s ease;
}

/* 不同温度范围的颜色增强 */
.temp-40, .temp-35 {
  opacity: 0.9;
}

.temp--10, .temp--15 {
  opacity: 0.9;
}
</style>